package com.xjrsoft.module.desktop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.common.enums.MenuType;
import com.xjrsoft.common.enums.YesOrNoEnum;
import com.xjrsoft.module.desktop.dto.AddDesktopSchemaDto;
import com.xjrsoft.module.desktop.dto.CopyDesktopSchemaDto;
import com.xjrsoft.module.desktop.dto.SetFirstDto;
import com.xjrsoft.module.desktop.dto.UpdateDesktopSchemaDto;
import com.xjrsoft.module.desktop.entity.DesktopHistory;
import com.xjrsoft.module.desktop.entity.DesktopSchema;
import com.xjrsoft.module.desktop.mapper.DesktopHistoryMapper;
import com.xjrsoft.module.desktop.mapper.DesktopSchemaMapper;
import com.xjrsoft.module.desktop.service.IDesktopSchemaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.module.system.entity.Menu;
import com.xjrsoft.module.system.mapper.MenuMapper;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 桌面设计历史记录 服务实现类
 * </p>
 *
 * @author tzx
 * @since 2023-04-13
 */
@Service
@AllArgsConstructor
public class DesktopSchemaServiceImpl extends ServiceImpl<DesktopSchemaMapper, DesktopSchema> implements IDesktopSchemaService {

    private final DesktopHistoryMapper desktopHistoryMapper;

    private final MenuMapper menuMapper;

    public final String componentPath = "/generator/desktop/home";

    public final String urlPath = "/desktop-home/";



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(AddDesktopSchemaDto dto) {
        DesktopSchema desktopSchema = BeanUtil.toBean(dto, DesktopSchema.class);

        long snowflakeNextId = IdUtil.getSnowflakeNextId();
        desktopSchema.setId(snowflakeNextId);

        //是否菜单
        if (desktopSchema.getIsMenu() == YesOrNoEnum.YES.getCode()) {
            Menu menu = new Menu();
            long menuId = IdUtil.getSnowflakeNextId();
            desktopSchema.setMenuId(menuId);
            menu.setId(menuId);
            menu.setCode(desktopSchema.getCode());
            menu.setName(desktopSchema.getName());
            menu.setParentId(dto.getParentId());
            menu.setTitle(desktopSchema.getName());
            menu.setSystemId(desktopSchema.getSystemId());
            menu.setIcon(dto.getIcon());
            menu.setPath(urlPath + snowflakeNextId);
            menu.setComponent(componentPath);
            menu.setMenuType(MenuType.FUNCTION.getCode());
            menu.setDisplay(YesOrNoEnum.YES.getCode());
            menu.setAllowModify(YesOrNoEnum.YES.getCode());
            menu.setAllowDelete(YesOrNoEnum.YES.getCode());
            menu.setOutLink(YesOrNoEnum.NO.getCode());
            menu.setKeepAlive(YesOrNoEnum.NO.getCode());
            menu.setRemark(desktopSchema.getRemark());
            menu.setSortCode(dto.getSortCode());

            menuMapper.insert(menu);
        }

        //如果此模板为首屏  需要吧其他的所有 设置为非首屏
        if (desktopSchema.getIsFirst() == YesOrNoEnum.YES.getCode()) {
            //将所有模板设置为 非默认
            LambdaQueryWrapper<DesktopSchema> select = Wrappers.lambdaQuery(DesktopSchema.class).eq(DesktopSchema::getIsFirst, YesOrNoEnum.YES.getCode()).select(DesktopSchema::getId);

            List<DesktopSchema> list = list(select);

            for (DesktopSchema schema : list) {
                schema.setIsFirst(YesOrNoEnum.NO.getCode());
            }
            updateBatchById(list);
        }
        save(desktopSchema);


        DesktopHistory history = new DesktopHistory();
        history.setSchemaId(desktopSchema.getId());
        history.setActivityFlag(YesOrNoEnum.YES.getCode());
        history.setJsonContent(desktopSchema.getJsonContent());
        desktopHistoryMapper.insert(history);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(UpdateDesktopSchemaDto dto) {
        DesktopSchema desktopSchema = BeanUtil.toBean(dto, DesktopSchema.class);

        //是否菜单
        if (desktopSchema.getIsMenu() == YesOrNoEnum.YES.getCode()) {
            Menu menu = new Menu();
            menu.setCode(desktopSchema.getCode());
            menu.setName(desktopSchema.getName());
            menu.setParentId(dto.getParentId());
            menu.setTitle(desktopSchema.getName());
            menu.setSystemId(desktopSchema.getSystemId());
            menu.setIcon(dto.getIcon());
            menu.setId(dto.getMenuId());
            //如果是已经存在菜单  默认是修改原菜单
            if (ObjectUtil.isNotNull(dto.getMenuId()) && !dto.getMenuId().equals(0L)) {
                menuMapper.updateById(menu);
            }
            //如果取消了菜单 菜单数据不在 需要重新新增
            else {
                long menuId = IdUtil.getSnowflakeNextId();
                desktopSchema.setMenuId(menuId);
                menu.setId(menuId);
                menu.setPath(urlPath + dto.getId());
                menu.setComponent(componentPath);
                menu.setComponentType(YesOrNoEnum.YES.getCode());
                menu.setMenuType(MenuType.FUNCTION.getCode());
                menu.setDisplay(YesOrNoEnum.YES.getCode());
                menu.setAllowModify(YesOrNoEnum.YES.getCode());
                menu.setAllowDelete(YesOrNoEnum.YES.getCode());
                menu.setOutLink(YesOrNoEnum.NO.getCode());
                menu.setKeepAlive(YesOrNoEnum.NO.getCode());
                menu.setRemark(desktopSchema.getRemark());

                menuMapper.insert(menu);
            }

            desktopSchema.setMenuId(menu.getId());
        }
        //如果不是菜单 需要把原菜单删除
        else {
            if(ObjectUtil.isNotNull(dto.getMenuId()) && dto.getMenuId() != 0L){
                menuMapper.deleteById(dto.getMenuId());
                desktopSchema.setMenuId(0L);
            }
        }

        //如果此模板为首屏  需要吧其他的所有 设置为非首屏
        if (desktopSchema.getIsFirst() == YesOrNoEnum.YES.getCode()) {
            //将所有模板设置为 非默认
            //将所有模板设置为 非默认
            LambdaQueryWrapper<DesktopSchema> select = Wrappers.lambdaQuery(DesktopSchema.class).eq(DesktopSchema::getIsFirst, YesOrNoEnum.YES.getCode()).select(DesktopSchema::getId);

            List<DesktopSchema> list = list(select);

            for (DesktopSchema schema : list) {
                schema.setIsFirst(YesOrNoEnum.NO.getCode());
            }
            updateBatchById(list);
        }

        updateById(desktopSchema);




        //修改原有历史记录 当前版本 标记
        DesktopHistory old = new DesktopHistory();
        old.setActivityFlag(YesOrNoEnum.NO.getCode());
        LambdaQueryWrapper<DesktopHistory> updateWrapper = Wrappers.lambdaQuery(DesktopHistory.class).eq(DesktopHistory::getSchemaId, desktopSchema.getId());
        desktopHistoryMapper.update(old, updateWrapper);

        //新增一条历史记录
        DesktopHistory history = new DesktopHistory();
        history.setSchemaId(desktopSchema.getId());
        history.setActivityFlag(YesOrNoEnum.YES.getCode());
        history.setJsonContent(desktopSchema.getJsonContent());
        desktopHistoryMapper.insert(history);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return true;
        }

        LambdaQueryWrapper<DesktopSchema> wrapper = Wrappers.lambdaQuery(DesktopSchema.class)
                .eq(DesktopSchema::getIsMenu,YesOrNoEnum.YES.getCode())
                .isNotNull(DesktopSchema::getMenuId)
                .in(DesktopSchema::getId, ids).select(DesktopSchema::getId,DesktopSchema::getMenuId);

        List<DesktopSchema> list = list(wrapper);
        List<Long> menuIds = list.stream().map(DesktopSchema::getMenuId).collect(Collectors.toList());

        if (menuIds.size() > 0) {
            menuMapper.deleteBatchIds(menuIds);
        }

        removeBatchByIds(ids);

        desktopHistoryMapper.delete(Wrappers.lambdaQuery(DesktopHistory.class).in(DesktopHistory::getSchemaId, ids));

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean copy(CopyDesktopSchemaDto dto) {

        DesktopSchema copySchema = getById(dto.getId());
        //不生成菜单
        copySchema.setId(null);
        copySchema.setIsFirst(YesOrNoEnum.NO.getCode());
        copySchema.setIsMenu(YesOrNoEnum.NO.getCode());
        copySchema.setMenuId(null);

        save(copySchema);

        DesktopHistory history = new DesktopHistory();
        history.setSchemaId(copySchema.getId());
        history.setActivityFlag(YesOrNoEnum.YES.getCode());
        history.setJsonContent(copySchema.getJsonContent());
        desktopHistoryMapper.insert(history);

        return true;
    }

    @Override
    public boolean setFirst(SetFirstDto dto) {
        //将所有模板设置为 非默认
        LambdaQueryWrapper<DesktopSchema> select = Wrappers.lambdaQuery(DesktopSchema.class).eq(DesktopSchema::getIsFirst, YesOrNoEnum.YES.getCode()).select(DesktopSchema::getId);

        List<DesktopSchema> list = list(select);

        for (DesktopSchema desktopSchema : list) {
            desktopSchema.setIsFirst(YesOrNoEnum.NO.getCode());
        }
        updateBatchById(list);

        //将当前模板所选模板设置为默认
        DesktopSchema schema = new DesktopSchema();
        schema.setId(dto.getId());
        schema.setIsFirst(YesOrNoEnum.YES.getCode());
        schema.setEnabledMark(YesOrNoEnum.YES.getCode());
        updateById(schema);

        return true;
    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public boolean importDesktopSchema(MultipartFile multipartFile) {
        //用流读取文件
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(multipartFile.getInputStream()));
        String line;
        StringBuilder content = new StringBuilder();
        // 读取想定文件
        while ((line = bufferedReader.readLine()) != null) {
            content.append(line);
        }

        DesktopSchema desktopSchema = JSONUtil.toBean(content.toString(), DesktopSchema.class);

        //不生成菜单
        desktopSchema.setId(null);
        desktopSchema.setIsFirst(YesOrNoEnum.NO.getCode());
        desktopSchema.setIsMenu(YesOrNoEnum.NO.getCode());
        desktopSchema.setMenuId(null);

        save(desktopSchema);


        DesktopHistory history = new DesktopHistory();
        history.setSchemaId(desktopSchema.getId());
        history.setActivityFlag(YesOrNoEnum.YES.getCode());
        history.setJsonContent(desktopSchema.getJsonContent());
        desktopHistoryMapper.insert(history);

        return true;
    }
}
